package de.hijacksoft.isle;

import static de.hijacksoft.isle.classes.Variables.*;

import java.util.ArrayList;
import java.util.Collections;

import net.londatiga.android.ActionItem;
import net.londatiga.android.QuickAction;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
import de.hijacksoft.isle.adapters.DBAdapter;
import de.hijacksoft.isle.classes.Item;
import de.hijacksoft.isle.adapters.MainListAdapter;
import de.hijacksoft.isle.classes.Variables;

public class ItemSelectActivity extends Activity {

    private static final String TAG = "ItemSelectActivity";
    /**
     * the List of all the items that are available in the database
     */
    private ArrayList<Item> infos;
    /**
     * the Adapter which manages the ListView and the ArrayList of Items
     */
    private MainListAdapter myAdapter;
    private DBAdapter adapter;
    // Views
    private Button add, clear, history, sort;
    /**
     * the List where all your items are shown
     */
    private ListView list;
    private EditText searchBar;
    private ArrayList<Item> itemsToAdd = new ArrayList<Item>();
    /**
     * the mode describing how to handle selected items
     */
    private int mode;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.itemselect);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);

        mode = getIntent().getExtras().getInt(KEY_MODE);

        initDB();
        createUI();
        initList();
        updateSortButton();

    }

    private void initDB() {
        adapter = new DBAdapter(this);
        adapter.open();
    }

    /**
     * changes the name and Icons of the SortButton
     */
    private void updateSortButton() {
        if (myAdapter.getCount() > 0) {
            sort.setEnabled(true);
            switch (Item.getSortMode()) {
                case Item.SORT_ALPHA:
                    sort.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.btn_alphabet, 0, 0);
                    sort.setText(R.string.sort_alphabet);
                    break;
                case Item.SORT_PERIOD:
                    sort.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.btn_period, 0, 0);
                    sort.setText(R.string.sort_period);
                    break;
                case Item.SORT_LASTBOUGHT:
                    sort.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.btn_lastbought, 0, 0);
                    sort.setText(R.string.sort_lastbought);
                    break;
            }
        } else {
            sort.setEnabled(false);
            sort.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.btn_alphabet, 0, 0);
            sort.setText(R.string.sort_alphabet);
        }
    }

    private void createUI() {

        add = (Button) findViewById(R.id.itemselect_btn_add);
        clear = (Button) findViewById(R.id.itemselect_btn_clear);
        list = (ListView) findViewById(R.id.itemselect_list_selectitem);
        history = (Button) findViewById(R.id.itemselect_btn_history);
        sort = (Button) findViewById(R.id.itemselect_btn_sort);

        history.setEnabled(false);
        sort.setVisibility(View.VISIBLE);
        
        LinearLayout listHeader = (LinearLayout)LayoutInflater.from(this).inflate(R.layout.searchbarheader, null);

        searchBar = (EditText) listHeader.findViewById(R.id.searchbarheader_edittext_search);
        
        list.addHeaderView(listHeader);
        
        // Build Sort QuickAction
        final QuickAction qa = new QuickAction(this);

        ActionItem qa_alphabet = new ActionItem();
        qa_alphabet.setTitle(getString(R.string.sort_alphabet));
        qa_alphabet.setIcon(getResources().getDrawable(R.drawable.qa_alphabet));
        qa.addActionItem(qa_alphabet);

        ActionItem qa_period = new ActionItem();
        qa_period.setTitle(getString(R.string.sort_period));
        qa_period.setIcon(getResources().getDrawable(R.drawable.qa_period));
        qa.addActionItem(qa_period);

        ActionItem qa_lastbought = new ActionItem();
        qa_lastbought.setTitle(getString(R.string.sort_lastbought));
        qa_lastbought.setIcon(getResources().getDrawable(R.drawable.qa_lastbought));
        qa.addActionItem(qa_lastbought);

        qa.setOnActionItemClickListener(new QuickAction.OnActionItemClickListener() {

            @Override
            public void onItemClick(int pos) {
                switch (pos) {
                    case 0:
                        Item.setSortMode(Item.SORT_ALPHA);
                        break;
                    case 1:
                        Item.setSortMode(Item.SORT_PERIOD);
                        break;
                    case 2:
                        Item.setSortMode(Item.SORT_LASTBOUGHT);
                        break;
                }
                updateSortButton();
                Collections.sort(infos);
                myAdapter.notifyDataSetChanged();
            }
        });

        sort.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                searchBar.setText("");
                Collections.sort(infos);
                myAdapter.notifyDataSetChanged();
                qa.show(sort);
            }
        });

        history.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent i = new Intent(ItemSelectActivity.this, HistoryActivity.class);
                i.putExtra(KEY_MODE, mode);
                startActivityForResult(i, ITEM_RETURNED);
            }
        });

        searchBar.addTextChangedListener(new TextWatcher() {

            @Override
            public void afterTextChanged(Editable arg0) {
                Collections.sort(infos);
                if (!searchBar.getText().toString().equals("")) {
                    int count = 0;
                    for (int i = 0; i < infos.size(); i++) {
                        if (infos.get(i).name.toLowerCase().contains(searchBar.getText().toString().toLowerCase())) {
                            //move items matching the search-criteria to the first positionF
                            Item item = infos.get(i);
                            infos.remove(item);
                            infos.add(count, item);
                            count++;
                        }
                    }
                }
                myAdapter.notifyDataSetChanged();
                list.setSelectionFromTop(0, 0);
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                //do nothing
            }

            @Override
            public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                //do nothing
            }
        });

        add.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                startActivityForResult(new Intent(ItemSelectActivity.this, ItemActivity.class), Variables.ITEM_EDIT);
            }
        });

        clear.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                clearListQuestion();
            }
        });

        list.setOnItemLongClickListener(new OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                if(arg2 > 0) ItemEditQuestion(arg2 - 1);
                return true;
            }
        });

        list.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                arg2--;
                itemsToAdd.add(infos.get(arg2));
                String text = "";
                switch (mode) {
                    case MODE_MAIN:
                        text = getString(R.string.itemaddedtolist).replace("$n", infos.get(arg2).name);
                        break;
                    case MODE_RECIPE:
                        text = getString(R.string.itemaddedtorecipe).replace("$n", infos.get(arg2).name);
                        break;
                }
                Toast.makeText(ItemSelectActivity.this, text, Toast.LENGTH_SHORT).show();
            }
        });

    }

    /**
     * Shows a dialog whether to edit or to delete an item 
     * @param position the position of the item in the list
     */
    private void ItemEditQuestion(final int position) {
        AlertDialog.Builder dB = new AlertDialog.Builder(this);
        dB.setTitle(infos.get(position).name);
        dB.setMessage(getString(R.string.editquestion));
        dB.setPositiveButton(getString(R.string.edit), new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int id) {
                Intent data = new Intent(ItemSelectActivity.this, ItemActivity.class);
                data.putExtra(KEY_ID, infos.get(position).id);
                startActivityForResult(data, Variables.ITEM_EDIT);
            }
        });
        dB.setNegativeButton(getString(R.string.delete), new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int id) {
                adapter.removeFromItemList(infos.get(position).id);
                infos.remove(position);
                myAdapter.notifyDataSetChanged();
            }
        });
        AlertDialog d = dB.create();
        d.show();
    }

    /**
     * disable/enable historyButton depending on whether a history exists or not
     */
    private void checkHistoryButton() {
        if (adapter.getHistory().size() > 0) {
            history.setEnabled(true);
        } else {
            history.setEnabled(false);
        }
    }

    private void initList() {
        if (infos == null) {
            infos = new ArrayList<Item>();
        }
        myAdapter = new MainListAdapter(this, R.layout.item, infos, adapter);
        list.setAdapter(myAdapter);
        LoadItemsTask lt = new LoadItemsTask();
        lt.execute(0);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case ITEM_RETURNED:
                if (resultCode == RESULT_OK) {
                    for (int i = 0; i < data.getExtras().size(); i++) {
                        //add items clicked inside historyactivity to the list to add to the main list
                        itemsToAdd.add(adapter.getItemById(data.getExtras().getInt("id_" + i)));
                    }
                    break;
                }
            case Variables.ITEM_EDIT:
                if (resultCode == RESULT_OK) {
                    initList();
                }
                break;
        }
        updateSortButton();
        myAdapter.notifyDataSetChanged();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        
        startActivity(new Intent(this, Preferences.class));
        return false;
    }

    public void clearListQuestion() {
        AlertDialog.Builder dB = new AlertDialog.Builder(this);
        dB.setTitle(R.string.clear);
        dB.setMessage(R.string.clearlist);
        dB.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int id) {
                adapter.clearItemList();
                infos.clear();
                myAdapter.notifyDataSetChanged();
            }
        });
        dB.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int id) {
                //do nothing
            }
        });
        AlertDialog d = dB.create();
        d.show();
    }

    @Override
    protected void onResume() {
        super.onResume();
        checkHistoryButton();
        myAdapter.notifyDataSetChanged();
    }

    /**
     * An AsyncTask to load all items from the Database into the list
     * @author HiJack Soft
     */
    private class LoadItemsTask extends AsyncTask<Integer, Integer, Integer> {

        @Override
        protected void onPreExecute() {
            list.setClickable(false);//disable clicking while theres a "loading" item
            infos.clear();
            myAdapter.setMode(MainListAdapter.PRICE, false);
            myAdapter.setMode(MainListAdapter.ICONS, false);
            myAdapter.setMode(MainListAdapter.CHECKBOX, false);
            myAdapter.setMode(MainListAdapter.AMOUNT, false);
            myAdapter.setMode(MainListAdapter.LASTBOUGHT, false);
            myAdapter.setMode(MainListAdapter.BARCODE, false);
            Item loadItem = new Item();
            loadItem.name = getString(R.string.loading);
            loadItem.image = null;
            loadItem.price = 13.37;
            infos.add(loadItem);//add an item showing "loading"
            myAdapter.notifyDataSetChanged();
        }

        @Override
        protected Integer doInBackground(Integer... arg) {
            infos = adapter.getAllItems();
            return null;
        }

        @Override
        protected void onPostExecute(Integer result) {
            list.setClickable(true);//enable the list again
            myAdapter = new MainListAdapter(ItemSelectActivity.this, R.layout.item, infos, adapter) {

                @Override
                public void onDataSetChange() {
                    updateSortButton();
                }
            };
            list.setAdapter(myAdapter);
            myAdapter.setMode(MainListAdapter.PRICE, true);
            myAdapter.setMode(MainListAdapter.ICONS, true);
            myAdapter.setMode(MainListAdapter.CHECKBOX, false);
            myAdapter.setMode(MainListAdapter.AMOUNT, true);
            myAdapter.setMode(MainListAdapter.LASTBOUGHT, false);
            myAdapter.setMode(MainListAdapter.BARCODE, true);
            myAdapter.notifyDataSetChanged();
            
            if(adapter.isOpen()) checkHistoryButton();

            searchBar.setVisibility(View.VISIBLE);
            
            list.setSelectionFromTop(1, searchBar.getHeight());
            
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        switch (keyCode) {

            case KeyEvent.KEYCODE_BACK:
                if (itemsToAdd.isEmpty()) {
                    ItemSelectActivity.this.setResult(RESULT_CANCELED, null); // Cancelled
                } else {
                    Intent data = new Intent();
                    for (int i = 0; i < itemsToAdd.size(); i++) {
                        data.putExtra("id_" + i, itemsToAdd.get(i).id);
                    }
                    ItemSelectActivity.this.setResult(RESULT_OK, data);       // Ok
                }
                break;
                
            case KeyEvent.KEYCODE_SEARCH:
                list.setSelectionFromTop(0, 0);
                new Handler(Looper.getMainLooper()).post(new Thread(){
                    @Override
                    public void run(){
                        do{
                            searchBar.requestFocus();
                            ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(searchBar,InputMethodManager.SHOW_FORCED); 
                        }while(!searchBar.hasFocus());
                    }
                });
                break;

        }

        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        adapter.close();
    }
    
}
